package com.xyzwps.ewa.modules.auth.password

open class DelegatedPasswordEncryptor(
    encryptors: Map<String, PasswordEncryptor>,
    defaultEncryptor: String
) : PasswordEncryptor {

    private val encryptors: Map<String, PasswordEncryptor>
    private val defaultEncryptor: String

    init {
        if (!encryptors.containsKey(defaultEncryptor)) {
            throw IllegalArgumentException("Argument defaultEncryptor must be in encryptors")
        }
        for (name in encryptors.keys) {
            if (!name.matches(Regex("^[a-zA-Z0-9_-]+$"))) {
                throw IllegalArgumentException("Invalid encryptor name: $name")
            }
        }

        this.defaultEncryptor = defaultEncryptor
        this.encryptors = mapOf(pairs = encryptors.entries.map { it.key to it.value }.toTypedArray())
    }

    override fun encrypt(password: String): String {
        val encryptor = encryptors[defaultEncryptor]!!
        return encryptor.encrypt(password) + ":" + defaultEncryptor
    }

    override fun verify(password: String, encrypted: String): Boolean {
        val index = encrypted.lastIndexOf(':')
        if (index < 0) {
            throw IllegalStateException("Invalid encrypted password: $encrypted")
        }

        val name = encrypted.substring(index + 1)
        val encryptor = encryptors[name] ?: throw IllegalStateException("Unknown encryptor: $name")
        return encryptor.verify(password, encrypted.substring(0, index))
    }
}